package com.itheima.server.service;

import cn.hutool.core.collection.CollUtil;
import com.itheima.commons.utils.Constants;
import com.itheima.dubbo.api.*;
import com.itheima.model.domain.*;
import com.itheima.model.dto.QuestionsDto;
import com.itheima.model.vo.ErrorResult;
import com.itheima.model.vo.ReportVo;
import com.itheima.model.vo.TestSoulVo;
import com.itheima.server.exception.BusinessException;
import com.itheima.server.interceptor.UserHolder;
import jdk.nashorn.internal.ir.annotations.Reference;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class TestService {
    @DubboReference
    private QuestionsApi questionsApi;
    @DubboReference
    private OptionsApi optionsApi;
    @DubboReference
    private TestSoulApi testSoulApi;
    @DubboReference
    private SoulResultApi soulResultApi;
    @DubboReference
    private ReportApi reportApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @Autowired
    private RedisTemplate redisTemplate;


    public Long replyQuestion(List<QuestionsDto> answers) {
        if (answers.size() != 10) {
            throw new BusinessException(ErrorResult.error());
        }
        //查询选项表计算总得分
        Integer score = optionsApi.concludeScore(answers);
        //查询该用户得分得到的结果
        SoulResult soulResult = soulResultApi.queryConclusion(score);
        //获取该次回答问题的等级
        String level = questionsApi.queryLevel(answers.get(0).getQuestionId());
        //添加report数据(更新或者修改)
        Report report = new Report();
        report.setResultId(soulResult.getId());///////
        report.setSoulScore(score);
        report.setUserId(UserHolder.getUserId());
        report.setSoulLevel(level);
        Long id= reportApi.saveAndUpdate(report);
        //修改用户的测灵魂答题等级
        UserInfo userInfo = new UserInfo();
        userInfo.setSoulLevel(level);
        userInfo.setId(UserHolder.getUserId());
        userInfoApi.updateSoulLevel(userInfo);
        //将用户结果保存/更新到redis中，用于查询相似的人
        String key = Constants.SIMILAR_LEVEL + level;
        String hashKey = Constants.SIMILAR_LEVEL_CONCLUSION + soulResult.getId();
        HashOperations<String, String, List<Long>> opsForHash = redisTemplate.opsForHash();
        List<Long> userids = opsForHash.get(key, hashKey);
        if (CollUtil.isEmpty(userids)) {
            userids = new ArrayList<>();
        }
        if (!userids.contains(UserHolder.getUserId())){//没有该用户就添加
            userids.add(UserHolder.getUserId());
            opsForHash.put(key, hashKey, userids);//相同等级，相同结果的人放进去
        }
        return id;
    }

    public List<TestSoulVo> testSoulList(Long userId) {
        //查询所有问卷(根据等级顺序排序)
        List<TestSoul> testSoulList = testSoulApi.list();
        if (CollUtil.isEmpty(testSoulList)) {
            return new ArrayList<>();
        }
        List<TestSoulVo> vo = new ArrayList<>();
        for (int i = 0; i < testSoulList.size(); i++) {
            //查询每个问卷的所有题目
            List<Questions> questionsList = questionsApi.listBySoulId(testSoulList.get(i).getId());//根据问卷的id查询题目
            Map<Long, List<Options>> rOptionsMap = new HashMap<>();
            for (int i1 = 0; i1 < questionsList.size(); i1++) {
                //查询每个题目的所有选项
                Long questionId = questionsList.get(i1).getId();//获取题目id
                List<Options> optionsList = optionsApi.listByQuestionsId(questionId);//根据题目id去查选项
                rOptionsMap.put(questionId, optionsList);
            }
            //构造TestSoulVo
            TestSoulVo testSoulVo = TestSoulVo.init(testSoulList.get(i), questionsList, rOptionsMap);
            //查询用户的level
            String soulLevel = userInfoApi.findById(userId).getSoulLevel();
            //根据用户level设置isLock参数，和cover参数
            testSoulVo.setIsLock(0);
            if (Integer.valueOf(soulLevel) < Integer.valueOf(testSoulList.get(i).getLevel())) {
                //此问卷上锁状态
                testSoulVo.setCover(testSoulList.get(i).getLockCover());
                testSoulVo.setIsLock(1);
            }
            //获取用户报告id(根据用户id和问卷等级去查询)
            Report report = reportApi.findByUserId(userId, testSoulList.get(i).getLevel());
            if(report!=null) {
                testSoulVo.setReportId(report.getId().toString());
            }
            vo.add(testSoulVo);
        }
        return vo;
    }

    public ReportVo queryReport(Long id) {
        Report report = reportApi.findByReportId(id);//根据报告id查询
        SoulResult soulResult=soulResultApi.findById(report.getResultId());
        ReportVo reportVo = new ReportVo();
        BeanUtils.copyProperties(soulResult,reportVo);
        //根据问卷调查等级去查询相似的人
        String soulLevel= report.getSoulLevel();
        String key = Constants.SIMILAR_LEVEL + soulLevel;
        String hashKey = Constants.SIMILAR_LEVEL_CONCLUSION + soulResult.getId();
        HashOperations<String, String, List<Long>> opsForHash = redisTemplate.opsForHash();
        List<Long> userids = opsForHash.get(key, hashKey);
        List<UserInfo> userInfoList=new ArrayList<>();
        if (!CollUtil.isEmpty(userids)) {
            //相似的人
            Long userId = UserHolder.getUserId();
            Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userids, null);
            Collection<UserInfo> userInfos = userInfoMap.values();
            userInfos.forEach(u->{
                UserInfo userInfo1 = new UserInfo();
                /*if(!u.getId().equals(userId)){
                    userInfo1.setId(u.getId());
                    userInfo1.setAvatar(u.getAvatar());
                    userInfoList.add(userInfo1);
                }*/
                userInfo1.setId(u.getId());
                userInfo1.setAvatar(u.getAvatar());
                userInfo1.setUserStatus(null);
                userInfoList.add(userInfo1);
            });
        }
        reportVo.setSimilarYou(userInfoList.size()==0?null:userInfoList);
        //维度
        ArrayList<Dimensions> dimensions = new ArrayList<>();
        dimensions.add(new Dimensions("抽象","80%"));
        dimensions.add(new Dimensions("外向","60%"));
        dimensions.add(new Dimensions("情商","70%"));
        dimensions.add(new Dimensions("判断","50%"));
        reportVo.setDimensions(dimensions);
        return reportVo;
    }
}
